#include "GUI_COM.h"
#include "GUI_CMD.h"
#include <cstring>
#include <cmath>
#include "mainwindow.h"

GUI_Chart_Struct GUI_Chart_Stu[4]=
{
    {0,0.0f,0.0f,0.0f,0,0,{0.0f,0.0f,0.0f,0.0f,0.1f,0.5f}},
    {0,0.0f,0.0f,0.0f,0,0,{0.0f,0.0f,0.0f,0.0f,0.1f,0.5f}},
    {0,0.0f,0.0f,0.0f,0,0,{0.0f,0.0f,0.0f,0.0f,0.1f,0.5f}},
    {0,0.0f,0.0f,0.0f,0,0,{0.0f,0.0f,0.0f,0.0f,0.1f,0.5f}}
};

void Ctrl_Value(GUI_Chart_Struct *Stu)
{
    if(!std::isfinite(Stu->Value))
    {
        Stu->Value=0.0f;
    }

    if(Stu->i==0)
    {
        Stu->Kalman_Filter_Stu.Measure_Now=Stu->Value;
        Stu->Kalman_Filter_Stu.Prediction_Last=Stu->Value;
        Stu->Kalman_Filter_Stu.Result_Last=Stu->Value;
        Stu->Kalman_Filter_Stu.Result_Now=Stu->Value;
        Stu->max=Stu->Value;
        Stu->min=Stu->Value;
        Stu->i++;
        return;
    }

    if(Stu->Value>Stu->max)
    {
        Stu->max=Stu->Value;
    }
    if(Stu->Value<Stu->min)
    {
        Stu->min=Stu->Value;
    }

    switch (Stu->Kalman_Filter)
    {
        case 1:
        {
            Stu->Kalman_Filter_Stu.Measure_Now=Stu->Value;
            Stu->Kalman_Filter_Stu=Kalman_Filter_Normal(Stu->Kalman_Filter_Stu);
            Stu->Value=Stu->Kalman_Filter_Stu.Result_Now;
            break;
        }
        case 2:
        {
            Stu->Kalman_Filter_Stu.Measure_Now=Stu->Value;
            Stu->Kalman_Filter_Stu=Kalman_Filter_Normal(Stu->Kalman_Filter_Stu);
            Stu->Kalman_Filter_Stu.Measure_Now=Stu->Kalman_Filter_Stu.Result_Now;
            Stu->Kalman_Filter_Stu=Kalman_Filter_Normal(Stu->Kalman_Filter_Stu);
            Stu->Value=Stu->Kalman_Filter_Stu.Result_Now;
            break;
        }
        default:
        {
            Stu->Kalman_Filter_Stu.Measure_Now=Stu->Value;
            Stu->Kalman_Filter_Stu.Prediction_Last=Stu->Value;
            Stu->Kalman_Filter_Stu.Result_Last=Stu->Value;
            Stu->Kalman_Filter_Stu.Result_Now=Stu->Value;
            break;
        }
    }

    Stu->i++;
}

uint8_t Get_Value(GUI_Chart_Struct *Stu,uint32_t i)
{
    switch(Stu->Value_Choose)
    {
        case GUI_Chart_Value_Choose_int32:
        {
            Stu->Value= float(*((int32_t*)(&i)));
            break;
        }
        case GUI_Chart_Value_Choose_uint32:
        {
            Stu->Value= float(*((uint32_t*)(&i)));
            break;
        }
        case GUI_Chart_Value_Choose_float:
        {
            Stu->Value= float(*((float*)(&i)));
            break;
        }
        case GUI_Chart_Value_Choose_bool:
        {
            Stu->Value= float(*((uint32_t*)(&i)));
            if(Stu->Value>0 || Stu->Value<0)
            {
                Stu->Value = 1.0f;
            }
            Stu->max=1;
            Stu->min=0;
            Stu->i++;
            return 1;
        }
        default:
        {
            Stu->Value=0.0f;
            return 0;
        }
    }

    Ctrl_Value(Stu);
    return 1;
}

uint8_t GUI_Chart(GUI_Struct GUI_Stu)
{
    GUI_Struct Stu;
    Stu.Flag=1;
    Stu.BCNT[0]=0;
    Stu.BCNT[1]=1;
    Stu.COM=GUI_Stu.COM;

    if(GUI_Stu.BCNT[1]!=17)
    {
        GUI_Error_Executing();
        return 0;
    }

    uint32_t buf[4];
    memcpy(buf,&GUI_Stu.DATA[0],16);

    uint8_t i=0;
    for(i=0;i<4;i++)
    {
        if(Get_Value(&GUI_Chart_Stu[i],buf[i]))
        {
            emit pw->Set_Value(i,QString::number(GUI_Chart_Stu[i].Value,'g',3));
            emit pw->Set_Log(QString("[Value %1] %2\n").arg(i+1).arg(GUI_Chart_Stu[i].Value));
            emit pw->Set_ChartView(i);
        }
    }

    GUI_Slave_Send(Stu);
    return 1;
}
